package com.app.synclistview;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;

import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;

public class SyncImageLoader {
	private Object lock = new Object();
	
	private boolean mAllowLoad = true;
	private boolean firstLoad = true;
	
	private int mStartLoadLimit = 0;
	
	private int mStopLoadLimit = 0;
	
	private Handler handler = new Handler();
	
	private HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
	
	public interface OnImageLoadListener {
		public void onImageLoad(Integer it,Drawable drawable);
		public void onError(Integer it);
	}
	
	public void setLoadedLimit(int mStartLoadLimit,int mStopLoadLimit){
		if(mStartLoadLimit>mStopLoadLimit){
			return ;
		}
		this.mStartLoadLimit = mStartLoadLimit;
		this.mStopLoadLimit = mStopLoadLimit;
	}
	
	public void restore(){
		mAllowLoad = true;
		firstLoad = true;
	}
	
	public void lock(){
		mAllowLoad = false;
		firstLoad = false;
	}
	
	public void unlock(){
		mAllowLoad = true;
		synchronized (lock) {
			lock.notifyAll();
		}
	}
	
	/**
	 * 加载图片，并且进行缓存
	 * @param t
	 * @param imageUrl
	 * @param listener
	 */
	public void loadImage(Integer t,String imageUrl,OnImageLoadListener listener){
		final OnImageLoadListener mListener = listener;
		final String mImageUrl = imageUrl;
		final Integer mt = t;
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				if(!mAllowLoad){
					DebugUtil.debug("prepare to load");
					synchronized (lock) {
						try {
							lock.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
				
				if(mAllowLoad && firstLoad){
					loadImage(mImageUrl,mt,mListener);
				}
				
				if(mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit){
					loadImage(mImageUrl, mt, mListener);
				}
			}
		});
	}
	
	
	private void loadImage(final String imageUrl,final Integer t,final OnImageLoadListener onListener){
		if(imageCache.containsKey(imageUrl)){
			SoftReference<Drawable> softReference = imageCache.get(imageUrl);
			final Drawable d = softReference.get();
			if(d != null){
				handler.post(new Runnable() {
					@Override
					public void run() {
						if (mAllowLoad) {
							onListener.onImageLoad(t, d);
						}
					}
				});
				return ;
			}
		}else{
			try {
				final Drawable d = loadImageFromUrl(imageUrl);
				if(d != null){
					imageCache.put(imageUrl, new SoftReference<Drawable>(d));
				}
				handler.post(new Runnable() {
					@Override
					public void run() {
						if(mAllowLoad){
							onListener.onImageLoad(t, d);
						}
					}
				});
			} catch (IOException e) {
				handler.post(new Runnable() {
					@Override
					public void run() {
						if(mAllowLoad){
							onListener.onError(t);
						}
					}
				});
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 从url中获取
	 * @param url
	 * @return
	 * @throws Exception 
	 */
	public Drawable loadImageFromUrl(String url) throws IOException{
		DebugUtil.debug(url);
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
			File f = new File(Environment.getExternalStorageDirectory()+"/TestSyncListView/"+MD5.getMD5(url));
			if(f.exists()){
				FileInputStream fis = new FileInputStream(f);
				Drawable d = Drawable.createFromStream(fis, "src");
				return d;
			}
			URL m = new URL(url);
			InputStream i = (InputStream) m.getContent();
			DataInputStream in = new DataInputStream(i);
			FileOutputStream out = new FileOutputStream(f);
			byte[] buffer = new byte[1024];
			int   byteread=0;
			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
			in.close();
			out.close();
			Drawable d = Drawable.createFromStream(i, "src");
			return d;
		}else{
			URL m = new URL(url);
			InputStream i = (InputStream) m.getContent();
			Drawable d = Drawable.createFromStream(i, "src");
			return d;
		}
	}
}
